Ubuntu 下通过 logrotate 和 crontab 自动按天分割 nginx 日志.

momo314相同方式共享非商业用途署名转载



1. 修改 nginx 配置文件

http 块中增加 log_format 配置,并调整 nginx log 保存位置:

cd /etc/nginx
vim nginx.conf # 可能是只读文件
http {
    # 省略其他配置项

    ##
    # Logging Settings
    ##

    log_format main '$http_host $remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /mnt/logs/nginx/access.log main;
    error_log /mnt/logs/nginx/error.log;


    # 省略其他配置项
}

注1:main 为 log_format 的 name,可自定义,但需要与 access_log 配置中保持一致。

2. 修改 logrotate 的 nginx 配置

cd /etc/logrotate.d
vim nginx # 可能是只读文件
/mnt/logs/nginx/*.log {
        su root root
        daily
        missingok
        rotate 14
        size 200M
        dateext
        compress
        delaycompress
        notifempty
        copytruncate
        create 0777 www-data www-data
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate >/dev/null 2>&1
        endscript
}

注01:文件中第一行为日志文件的位置,应该与 nginx.conf 中配置的 access_log 路径相对应。

注02:可以使用 su root root,来指定使用root权限执行。

注03:daily,每天执行一次,对应的,还有weekly, monthly。

注04:missingok,允许日志文件不存在,不报错。

注05:srotate 14,保留最近14个日志文件。

注06:dateext,使用日志作为备份文件的后缀名,eg: access.log-20191110, access.log-20191110.gz。

注07:compress,使用gzip压缩日志,对应的,nocompress 为不压缩日志。

注08:delaycompress,与compress配合使用,转存的文件在下一次执行时才会被压缩。

注09:copytruncate,用于还在写入中的日志文件,先将文件内容拷贝到其他文件,然后再清空文件,因为拷贝和清空存在时间差,会导致部分日志丢失。

注10:sharedscripts,所有日志文件轮转完成后统一执行一次脚本,而非每个文件执行一次。

注11:prerotate,logrotate转储之前需要执行的脚本。

注12:postrotate,logrotate转储之后需要执行的脚本,通常用于重启服务之类的操作。

注13:create,使用指定的 mode, user, group 来创建新文件。

注14:www-data, 因为nginx默认使用的是www-data用户。

3. 设置 logrotate.d/nginx 配置文件权限

为防止后续在对 logrotate 进行测试的过程中出现权限问题,需要将 logrotate.d/nginx 配置文件的权限设置为 0644

cd /etc/logrotate.d
sudo chmod 0644 nginx

以应对如下报错信息:

error: Ignoring syslog because of bad file mode - must be 0644 or 0444

4. 测试日志分割

cd /usr/sbin
sudo ./logrotate -f /etc/logrotate.d/nginx

如果日志文件较大,可能这里需要等待一会儿,如果没有报错的话,切换到日志目录,查看日志文件是否分割成功。

如果出现以下错误信息:

error: skipping "/mnt/logs/nginx/access.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.
error: skipping "/mnt/logs/nginx/error.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.

则需要在 logrotate.d/nginx 配置文件中设置 su root root

如果出现以下错误信息:

error: error switching euid to 0 and egid to 0: Operation not permitted
error: error creating output file /var/lib/logrotate/status.tmp: Permission denied

一般来说,有两个原因

  1. 第一个报错明显是说在生成新文件时,没有权限设置euid。就需要检查一下 logrotate.d/nginx 配置文件中指定的 create 配置, 一般我会配置为 create 0777 www-data www-data (www-data为nginx默认用户)。
  2. 第二个报错一般是由于没有使用 sudo 来执行 logrotate 命令导致的。

4. 配置 crontab

cd /etc
vim crontab # 可能是只读文件

在 crontab 中新增如下行,代表在每天的 00:00 执行。

# m h dom mon dow user  command
0  0    * * *   root    /usr/sbin/logrotate -f /etc/logrotate.d/nginx
#
✎﹏ 本文来自于 momo314和他们家的猫,文章原创,转载请注明作者并保留原文链接。